<template>
  <div>
      <!-- 面包屑导航 -->
      <el-breadcrumb separator-class="el-icon-arrow-right">
        <el-breadcrumb-item :to="{path:'/home'}">首页</el-breadcrumb-item>
        <el-breadcrumb-item>商品管理</el-breadcrumb-item>
        <el-breadcrumb-item>参数列表</el-breadcrumb-item>
      </el-breadcrumb>
      <!-- 卡片视图 -->
      <el-card>
        <!-- 警告提示 -->
        <el-alert
          title="注意：只允许为第三级分类设置相关参数！"
          type="warning"
          :closable="false"
          show-icon>
        </el-alert>
        <!-- 级联选择器 -->
        <span>选择商品分类：</span>
        <el-cascader
          v-model="selectedKeys"
          :options="categoryList"
          :props="categoryProps"
          @change="handleChange"
          size="medium"></el-cascader>
          <!-- 页签切换 -->
          <!-- activeName表示选择不同标签对应el-tab-pane中name属性的值 -->
          <el-tabs v-model="activeName" @tab-click="handleTabClick">
            <!-- 动态参数区 -->
            <el-tab-pane label="动态参数" name="many">
              <el-button type="primary" :disabled="isBtnDisabled" @click='addDialogVisible=true'>添加参数</el-button>
              <!-- 动态参数表格 -->
              <el-table :data="manyTableData" border stript>
                <!-- 展开行 -->
                <el-table-column type=expand>
                  <template slot-scope="scope">
                        <el-tag @close="removeTag(scope.row,index)" v-for="(item,index) in scope.row.attr_vals" :key="index" closable>{{ item }}</el-tag>
                        <!-- 输入框与按钮的切换 -->
                        <el-input
                          class="input-new-tag"
                          v-if="scope.row.inputVisible"
                          v-model="scope.row.inputValue"
                          ref="saveTagInput"
                          size="small"
                          @keyup.enter.native="handleInputConfirm(scope.row)"
                          @blur="handleInputConfirm(scope.row)"
                        >
                        </el-input>
                        <el-button v-else size="small" @click="showInput(scope.row)">+ New Tag</el-button>
                  </template>
                </el-table-column>
                <!-- 序号 -->
                <el-table-column type='index'></el-table-column>
                <el-table-column label="参数名称" prop="attr_name"></el-table-column>
                <el-table-column label="操作">
                  <template slot-scope="scope">
                    <!-- 修改角色信息按钮 -->
                    <el-button
                    type="primary"
                    icon="el-icon-edit"
                    size="mini"
                    @click='editParamsBtn(scope.row)'
                    >编辑</el-button>
                    <!-- 删除角色按钮 -->
                    <el-button
                    type="danger"
                    icon="el-icon-delete"
                    size="mini"
                    @click='removeParams(scope.row)'
                    >删除</el-button>
                  </template>
                </el-table-column>
              </el-table>
            </el-tab-pane>
            <!-- 静态属性区 -->
            <el-tab-pane label="静态属性" name="only">
              <el-button type="primary" :disabled="isBtnDisabled" @click='addDialogVisible=true'>添加属性</el-button>
              <!-- 静态属性表格 -->
              <el-table :data="onlyTableData" border stript>
                <!-- 展开行 -->
                <el-table-column type=expand>
                  <template slot-scope="scope">
                        <el-tag @close="removeTag(scope.row,index)" v-for="(item,index) in scope.row.attr_vals" :key="index" closable>{{ item }}</el-tag>
                        <!-- 输入框与按钮的切换 -->
                        <el-input
                          class="input-new-tag"
                          v-if="scope.row.inputVisible"
                          v-model="scope.row.inputValue"
                          ref="saveTagInput"
                          size="small"
                          @keyup.enter.native="handleInputConfirm(scope.row)"
                          @blur="handleInputConfirm(scope.row)"
                        >
                        </el-input>
                        <el-button v-else size="small" @click="showInput(scope.row)">+ New Tag</el-button>
                  </template>
                </el-table-column>
                <!-- 序号 -->
                <el-table-column type='index'></el-table-column>
                <el-table-column label="属性名称" prop="attr_name"></el-table-column>
                <el-table-column label="操作">
                  <template slot-scope="scope">
                    <!-- 修改角色信息按钮 -->
                    <el-button
                    type="primary"
                    icon="el-icon-edit"
                    size="mini"
                    @click='editParamsBtn(scope.row)'
                    >编辑</el-button>
                    <!-- 删除角色按钮 -->
                    <el-button
                    type="danger"
                    icon="el-icon-delete"
                    size="mini"
                    @click='removeParams(scope.row)'
                    >删除</el-button>
                  </template>
                </el-table-column>
              </el-table>
            </el-tab-pane>
          </el-tabs>
      </el-card>
      <!-- 添加参数和属性对话框（共用） -->
      <el-dialog
        :title="title"
        :visible.sync="addDialogVisible"
        width="50%"
        @close='closeAddDialog'>
        <el-form label-width="80px" :model='addForm' :rules='addFormRules' ref='addFormRef'>
            <el-form-item :label='label' prop='attr_name'>
                <el-input v-model='addForm.attr_name'></el-input>
            </el-form-item>
        </el-form>
        <span slot="footer">
          <el-button @click="addDialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="addParams">确 定</el-button>
        </span>
      </el-dialog>
      <!-- 编辑参数和属性对话框 -->
      <!-- 共用了添加的验证规则 -->
      <el-dialog
        :title="title"
        :visible.sync="editDialogVisible"
        width="50%"
        @close='closeEditDialog'>
        <el-form label-width="80px" :model='editForm' :rules='addFormRules' ref='editFormRef'>
            <el-form-item :label='label' prop='attr_name'>
                <el-input v-model='editForm.attr_name'></el-input>
            </el-form-item>
        </el-form>
        <span slot="footer">
          <el-button @click="editDialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="editParams">确 定</el-button>
        </span>
      </el-dialog>
  </div>
</template>

<script>
export default {
    name:'Params',
    data(){
      return{
        // 保存获取的所有商品分类列表
        categoryList:[],
        // 保存级联选择器的id值
        selectedKeys:[],
        // 级联选择器配置
        categoryProps:{
            expandTrigger:'hover',
            value:'cat_id',
            label:'cat_name'
        },
        // 默认被激活的页签名称（页签选择器）
        // mony和only是为了请求数据库更简单而指定的
        activeName:'many',
        // 控制页签中添加按钮的禁用状态
        isBtnDisabled:true,
        // 动态参数数据
        manyTableData:[],
        // 静态属性数据
        onlyTableData:[],
        // 控制添加参数对话框是否出现
        addDialogVisible:false,
        // 添加参数或属性的对象
        addForm:{
          attr_name:''
        },
        // 验证规则
        addFormRules:{
          attr_name:[
            {required:true,message:'请输入参数名称',trigger:'blur'},
            {min:1,max:10,message:'长度在 4 到 10 个字符',trigger:'blur'}
          ]
        },
        // 控制编辑对话框是否出现
        editDialogVisible:false,
        // 保存编辑对话框中最新的名称
        editForm:{
          attr_name:'',
          cat_id:0,
          attr_id:0
        },
      }
    },
    created(){
      // 获取全部的商品分类列表
      this.getCategoryList()
    },
    methods:{
      // 获取分类列表（用于级联选择器）
      async getCategoryList(){
        const {data:res} = await this.$http.get('categories',{params:{type:3}})
        if(res.meta.status!==200) return this.$message.error('获取全部商品分类列表失败')
        // console.log(res.data);
        // 保存
        this.categoryList=res.data
      },
      // 级联选择器发生改变时触发
      handleChange(){
        // 获取参数列表
        this.getParamsList()
      },
      // 获取参数列表
      async getParamsList(){
        // 当选择了三级分类时，解除页签切换中按钮的禁用
        if(this.selectedKeys.length===3){
          // 不禁用
          this.isBtnDisabled=false
          // 发送请求获取数据
          const {data:res} = await this.$http.get('categories/'+this.selectedKeys[2]+'/attributes',{params:{sel:this.activeName}})
          if(res.meta.status!==200) return this.$message.error('获取参数信息失败')

          // 将参数列表 attr_vals以逗号分割为数组
          res.data.forEach(item=>{
            // 去除空字符串对展示的影响
            item.attr_vals = item.attr_vals === '' ? [] : item.attr_vals.split(',')
            // 给每一个参数展开列都赋予单独的属性，用来保存自己研读的信息
            // 控制展开列中输入框的显示与隐藏
            item.inputVisible = false
            // 双向绑定
            item.inputValue = ''
          })
          // console.log(res.data);

          // console.log(this.selectedKeys[2]);
          if(this.activeName==='many'){
            this.manyTableData=res.data
          }else{
            this.onlyTableData=res.data
          }
        }else{
          // 重置选中的 cat_id
          this.selectedKeys=[]
          // 重置表格，使表格不显示内容
          this.manyTableData=[]
          this.onlyTableData=[]
          // 提示
          this.$message.warning('只允许更改三级分类的参数！')
        }
      },
      // tab页签点击事件处理函数
      handleTabClick(tab, event) {
        // console.log(this.activeName);
        // 当页签图标发生切换时，再次获取数据
        this.getParamsList()
      },
      // 对话框关闭
      closeAddDialog(){
        // 重置表单
        this.$refs.addFormRef.resetFields()
      },
      // 添加参数或属性预验证与发送请求
      addParams(){
        this.$refs.addFormRef.validate(async boolean=>{
          if(!boolean) return this.$message.error('添加参数或属性预验证失败')
          const {data:res} = await this.$http.post(`categories/${this.selectedKeys[2]}/attributes`,{attr_name:this.addForm.attr_name,attr_sel:this.activeName,})
          if(res.meta.status!==201) return this.$message.error('添加参数失败')
          this.$message.success('添加参数成功')
          // 获取参数列表
          this.getParamsList()
          this.addDialogVisible=false
        })
      },
      // 点击编辑参数按钮
      editParamsBtn(params){
        this.editDialogVisible=true
        // console.log(edit);
        // 保存edit传递过来的值，数据请求时需要
        this.editForm.cat_id=params.cat_id
        this.editForm.attr_id=params.attr_id
        // console.log(this.editForm);
        // console.log(this.selectedKeys[2]);
      },
      // 清空输入框
      closeEditDialog(){
        this.$refs.editFormRef.resetFields()
      },
      // 编辑参数或属性预验证与发送请求
      editParams(){
        this.$refs.editFormRef.validate(async boolean=>{
          if(!boolean) return this.$message.error('修改参数和属性预验证失败')
          const {data:res} = await this.$http.put(`categories/${this.editForm.cat_id}/attributes/${this.editForm.attr_id}`,{attr_name:this.editForm.attr_name,attr_sel:this.activeName})
          if(res.meta.status!==200) return this.$message.error('修改参数和属性失败')
          this.$message.success('修改参数或属性成功')
          this.getParamsList()
          this.editDialogVisible=false
        })
      },
      // 删除参数或属性
      async removeParams(params){
        const confirmResult = await this.$confirm('是否要删除此参数或属性？','提示',{
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).catch(err=>err)
        if(confirmResult!=='confirm') return this.$message.info('已经取消删除')
        const {data:res} = await this.$http.delete(`categories/${params.cat_id}/attributes/${params.attr_id}`)
        if(res.meta.status!==200) return this.$message.error('删除参数或属性失败')
        this.getParamsList()
        this.$message.success('删除参数或属性成功')
      },
      // 文本框失去焦点或按下 Enter键触发
      async handleInputConfirm(row){
        // 如果没有输入或输入的全是空格
        if(row.inputValue.trim().length===0){
          row.inputValue=''
          row.inputVisible=false
          return
        }
        // console.log(row);
        // 将新的参数值添加到数组中
        row.attr_vals.push(row.inputValue.trim())
        row.inputValue=''
        row.inputVisible=false
        // 发送请求，添加参数值
        const {data:res} = await this.$http.put(`categories/${row.cat_id}/attributes/${row.attr_id}`,{
          attr_name:row.attr_name,
          attr_sel:row.attr_sel,
          attr_vals:row.attr_vals.join(',')
        })
        if(res.meta.status!==200) return this.$message.error('删除参数值或属性值失败')
        // 重新获取参数列表，并不需要(上面已经将新的参数值添加到数组中，会自动渲染显示)，
        // 不然会自动关闭展开行，体验不好
        // this.getParamsList()
        this.$message.success('删除参数值或属性值成功')
      },
      // 按下切换按钮触发
      showInput(row){
        row.inputVisible = true
        // 自动获取焦点 (页面重新渲染之后再执行里面的代码)
        this.$nextTick(()=> {
          this.$refs.saveTagInput.$refs.input.focus();
        });
      },
      // 删除参数值或属性值
      async removeTag(row,index){
        row.attr_vals.splice(index,1)
        // 发送请求，删除参数值
        const {data:res} = await this.$http.put(`categories/${row.cat_id}/attributes/${row.attr_id}`,{
          attr_name:row.attr_name,
          attr_sel:row.attr_sel,
          attr_vals:row.attr_vals.join(',')
        })
        if(res.meta.status!==200) return this.$message.error('删除参数值或属性值失败')
        this.$message.success('删除参数值或属性值成功')
      }
    },
    computed:{
      // 动态指定 添加参数和属性的对话框title
      title(){
        if(this.activeName==='many') return '添加参数'
        return '添加属性'
      },
      label(){
        if(this.activeName==='many') return '参数名称'
        return '属性名称'
      }
    }
}
</script>

<style scoped>
  .el-card{
    margin: 20px;
  }
  .el-cascader{
    margin-top: 20px;
  }
  .el-table{
    margin-top: 20px;
  }
  .el-tag{
    margin: 5px;
  }
  /* 展开行中切换的文本输入框 */
  .input-new-tag{
    width: 100px;
  }
</style>